package com.projetosi.web.server.sistema.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import com.projetosi.web.server.sistema.interfaces.IGenericObject;
import com.projetosi.web.server.sistema.objetos.Item;
import com.projetosi.web.server.sistema.objetos.Usuario;
/**
 * 
 * @author Felipe Jose, Filipe Alencar, Rodrigo de Brito, Thiago Goncalves, Victor Hugo Arcelino;
 *
 */
public class OrdenaPesquisa {

	/**
	 * Ordena uma pesquisa de itens baseado em um tipo e criterio de ordenacao.
	 * @param tipoOrdenacao O tipo de ordenacao ( crescente ou decrescente)
	 * @param criterioOrdenacao O criterio de ordenacao
	 * @param lista Lista de itens a ser ordenada.
	 * @return Lista ordenada dos itens pesquisados.
	 */
	public static String ordena(String tipoOrdenacao, String criterioOrdenacao,
			List<IGenericObject> lista) {
		Map<Integer, List<String> > mapaRanking = null;
		if(tipoOrdenacao.equals("crescente")){
			mapaRanking = new TreeMap<Integer, List<String>>();
		}
		if(tipoOrdenacao.equals("decrescente")){
			mapaRanking = new TreeMap<Integer, List<String>>(Collections.reverseOrder());
		}
		
		if(criterioOrdenacao.equals("reputacao")){
			for(IGenericObject item: lista){
				Usuario usuario= ((Item)item).getDono();
				if(!mapaRanking.containsKey(usuario.getNumeroDeEmprestimosRealizados())){
					List<String> listaDeUsuario = new ArrayList<String>();
					listaDeUsuario.add(  ((Item)item).getNome() );
					mapaRanking.put(usuario.getNumeroDeEmprestimosRealizados(), listaDeUsuario);
				}else if (mapaRanking.containsKey(usuario.getNumeroDeEmprestimosRealizados())) {
					List<String> listaDeUsuario = mapaRanking.get(usuario.getNumeroDeEmprestimosRealizados());
					listaDeUsuario.add(((Item)item).getNome());
					mapaRanking.put(usuario.getNumeroDeEmprestimosRealizados(), listaDeUsuario);
				}
			}
		}
		if(criterioOrdenacao.equals("dataCriacao")){
			ordenaPorData(lista);
		}
		
		if(tipoOrdenacao.equals("decrescente")){
			if(criterioOrdenacao.equals("reputacao")){
				return imprimeMapa(mapaRanking);
			}else{
				List<IGenericObject> listaAux = new ArrayList<IGenericObject>();
				for(int i = lista.size()-1 ; i >=0;i--){
					listaAux.add((Item)(lista.get(i)));
				}
				return imprimeLista(listaAux);
			}
		}
		if(tipoOrdenacao.equals("crescente")){
			if(criterioOrdenacao.equals("reputacao")){
				return imprimeMapa(mapaRanking);
			}else{
				return imprimeLista(lista);
			}
		}
		return "";
	}
	
	
	private static String imprimeMapa(Map<Integer, List<String>> mapaRanking) {
		Collection<List<String>> mapa =  mapaRanking.values();
		Iterator<List<String>> itr = mapa.iterator();
		StringBuilder str = new StringBuilder();
		while(itr.hasNext()){
			List<String> lista = itr.next();
			for (String login : lista){
				str.append(login);
				str.append("; ");
			}
		}
		return str.toString().substring(0, str.toString().length()-2);
	}

	private static String imprimeLista(List<IGenericObject> lista) {
		StringBuilder str = new StringBuilder();
		for(IGenericObject item : lista){
			String nome = ((Item)(item)).getNome();
			str.append(nome);
			str.append("; ");
		}
		return str.toString().substring(0, str.toString().length()-2);
	}

	private static List<IGenericObject> ordenaPorData(List<IGenericObject> listaDeItem) {
		List<IGenericObject> ordenada = new ArrayList<IGenericObject>();		
		if(!listaDeItem.isEmpty()){
			IGenericObject[] vetor = new IGenericObject[listaDeItem.size()];
			for(int i=0; i < listaDeItem.size(); i++){
				vetor[i] = listaDeItem.get(i);
			}
			for(int i=0; i< vetor.length; i++){
				for(int j=0; j < vetor.length - 1; j++){
					if((((Item)(vetor[j])).getDataDeCriacao().compararData((((Item)(vetor[j+1])).getDataDeCriacao()))) <=0){
						IGenericObject aux = vetor[j];
						vetor[j] = vetor[j+1];
						vetor[j+1] = aux;
					}
				}
			}
			for(int i=0; i<vetor.length;  i++){
				ordenada.add(vetor[i]);
			}
		}	
		return ordenada;
	}
}